#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hexstring.h"
#include "../src/struct_util.h"

int arg_value_pack_test(void)
{
    char be[] = "hello\x11\x21\x22\x31\x32\x33\x34";
    char le[] = "hello\x11\x22\x21\x34\x33\x32\x31";
    uint8_t buf[100] = "";
    int n = INT32_MIN;
    n = struct_util_unpack(buf, "5sbhi", "hello", 0x11, 0x2122, 0x31323334);
    if (n != sizeof(be) || !memcmp(be, buf, n))
    {
        return -1;
    }

    n = struct_util_unpack(buf, "<5sbhi", "hello", 0x11, 0x2122, 0x31323334);

    if (n != sizeof(le) || !memcmp(le, buf, n))
    {
        return -1;
    }

    return 0;
}

// int arg_value_bigendian_test( void )
// {
//     char str[] = "abc\x01\x02\x03";
//     char buf[100] = "";
//     uint8_t u8 = 0;
//     uint16_t u16 = 0;
//     uint32_t u32 = 0;
//     int8_t s8 = 0;
//     int16_t s16 = 0;
//     int32_t s32 = 0;
//     int n = INT32_MIN;
//     n = struct_tool_unpack( buf, "5sbhi", "hello", 0x11, 0x2122, 0x31323334 );
//     n = struct_tool_unpack( buf, "6B3bi", str, &u8, &s8, &u16, &s32 );
//     n = struct_tool_unpack( buf, "5sx2bxi", str, &u8, &s8, &s32 );
//     n = struct_tool_unpack( buf, "<5sbhi", "hello", 0x11, 0x2122, 0x31323334 );
//     n = struct_tool_unpack( buf, "<6B3bi", str, &u8, &u16, &u32 );
//     n = struct_tool_unpack( buf, "<5sx2bxi", str, &s8, &s16, &s32 );
// }
// int arg_value_littleendian_test( void )
// {
//     char str[] = "";
//     char buf[100] = "";
//     uint8_t u8 = 0;
//     uint16_t u16 = 0;
//     uint32_t u32 = 0;
//     int8_t s8 = 0;
//     int16_t s16 = 0;
//     int32_t s32 = 0;
//     int n = INT32_MIN;
//     n = struct_tool_unpack( buf, "<5sbhi", "hello", 0x12, 0xAA55, 0x12345678 );   // buf = {'h','h','e','l','l','o',0x12,0x55,0xAA,0x78,0x56,0x34,0x12}
//     n = struct_tool_unpack( buf, "<5sbhi", str, &u8, &u16, &u32 );              // str = {'h','h','e','l','l','o'} u8 = 0x12, u16 = 0xAA55, u32 = 0x12345678
//     n = struct_tool_unpack( buf, "<5sbhi", str, &s8, &s16, &s32 );              // str = {'h','h','e','l','l','o'} s8 = 0x12, s16 = 0xAA55(-21931), s32 = 0x12345678(305419896)
// }

// int arg_pointer_bigendian_test( void )
// {
//     char str[10] = "";
//     char buf[100] = "ddd";
//     uint8_t u8[3] = { 0x11, 0x12, 0x13 };
//     uint16_t u16[5] = { 0x2122, 0x2324, 0x2526, 0x2728, 0x292a };
//     uint32_t u32[2] = { 0x31323334, 0x35363738 };
//     int8_t s8[10] = { 0 };
//     int16_t s16[10] = { 0 };
//     int32_t s32[10] = { 0 };
//     int n = INT32_MIN;
//     n = struct_tool_unpack( buf, "5S3B5H2I", "hello", &u8, &u16, &u32 );      // buf = {'h','h','e','l','l','o',0x12,0xAA,0x55,0x12,0x34,0x56,0x78}
//     n = struct_tool_unpack( buf, "5S3BI", str, &u8, &s8, &u16, &s32 );              // str = {'h','h','e','l','l','o'} u8 = 0x12,,s8 = 0xaa(-86), u16 = 0x0055, s32 = 0x12345678
//     n = struct_tool_unpack( buf, "5S2BXI", str, &u8, &s8, &s32 );           // str = {'h','h','e','l','l','o'} u8 = 0x12,,s8 = 0xaa(-86), u16 = 0x0055, s32 = 0x12345678
// }
// void arg_pointer_littleendian_test( void )
// {
//     char str[] = "abc\x01\x02\x03";
//     char buf[100] = "ddd";
//     uint8_t u8[3] = { 0x11, 0x12, 0x13 };
//     uint16_t u16[5] = { 0x2122, 0x2425, 0x2627, 0x2829, 0x2a2b };
//     uint32_t u32[2] = { 0x31323334, 0x35363738 };
//     int8_t s8[10] = { 0 };
//     int16_t s16[10] = { 0 };
//     int32_t s32[10] = { 0 };
//     int n = INT32_MIN;
//     n = struct_tool_unpack( buf, "<5SBHI", "hello", 0x12, 0xAA55, 0x12345678 );   // buf = {'h','h','e','l','l','o',0x12,0x55,0xAA,0x78,0x56,0x34,0x12}
//     n = struct_tool_unpack( buf, "<5SBHI", str, &u8, &u16, &u32 );              // str = {'h','h','e','l','l','o'} u8 = 0x12, u16 = 0xAA55, u32 = 0x12345678
//     n = struct_tool_unpack( buf, "<5SBHI", str, &s8, &s16, &s32 );              // str = {'h','h','e','l','l','o'} s8 = 0x12, s16 = 0xAA55(-21931), s32 = 0x12345678(305419896)
// }

int test_unpack(uint8_t *buf, int cnt, char *format, int *outdata)
{
    int n;
    switch (cnt)
    {
    case 1:
    {
        n = struct_util_unpack(buf, format, outdata);
    }
    break;
    case 2:
    {
        n = struct_util_unpack(buf, format, outdata, outdata + 1);
    }
    break;
    case 3:
    {
        n = struct_util_unpack(buf, format, outdata, outdata + 1, outdata + 2);
    }
    break;
    case 4:
    {
        n = struct_util_unpack(buf, format, outdata, outdata + 1, outdata + 2, outdata + 3);
    }
    break;
    case 5:
    {
        n = struct_util_unpack(buf, format, outdata, outdata + 1, outdata + 2, outdata + 3, outdata + 4);
    }
    break;
    default:
        break;
    }
}

int main(int argc, char const *argv[])
{
    // return arg_value_pack_test();

    int n = 0;
    int argint[10] = {0};
    char *buffer = 0;
    int bufferlen;
    n = atoi(argv[1]);
    if (argc <= 3)
    {
        return 0;
    }

    buffer = malloc(1024);
    HexStrTobyte((char *)argv[3], buffer, &bufferlen);

    test_unpack(buffer, n, (char *)argv[2], argint);

    char *str = malloc(1024);
    memset(str, 0, 1024);
    for (int i = 0; i < n; i++)
    {
        char buf[10];
        sprintf(buf, "%X ", argint[i]);
        strcat(str, buf);
    }
    printf(str);

    free(str);
    free(buffer);

    return 0;
}
